package com.stm.bi.report;

import com.stm.base.api.RegionRemoteService;
import com.stm.base.dto.query.RegionListQry;
import com.stm.base.dto.vo.RegionVO;
import com.stm.bi.constant.IndexConstants;
import com.stm.bi.dto.query.RegionalSaleQry;
import com.stm.bi.model.Chart;
import com.stm.framework.core.util.FileResourceLoader;
import com.stm.framework.dbcp.JdbcService;
import com.stm.framework.dto.Response;
import com.stm.ucenter.api.BizCustomerRemoteService;
import com.stm.ucenter.dto.query.BizCustomerListQry;
import com.stm.ucenter.dto.vo.BizCustomerVO;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import static com.stm.saas.constant.IndexConstants.BUSINESS_ID_FIELD_NAME;
import static com.stm.saas.constant.IndexConstants.NUMBER_OF_DEALING_FIELD_NAME;

/**
 * @author liuyx
 * @date 2025/2/14 9:09
 */
@Component
public class BizCustomersRankChartToBQueryExe extends AbsChartQueryExe<RegionalSaleQry, Chart> {
    @Resource
    private JdbcService jdbcService;

    @Resource
    private BizCustomerRemoteService bizCustomerRemoteService;

    @Resource
    private RegionRemoteService regionRemoteService;


    @Override
    public Chart query(Long orgId, String orgNo, RegionalSaleQry query) {

        Chart chart = new Chart();
        List<List<Object>> datas = new ArrayList<>();

        // 根据部门id查询该部门下所有B端客户信息
        BizCustomerListQry bizQry = new BizCustomerListQry();
        bizQry.setChildId(query.getDeptId());
        Response<List<BizCustomerVO>> bizResponse = bizCustomerRemoteService.selectList(bizQry);
        if (!bizResponse.isSuccess() || bizResponse.getData().isEmpty()) {
            return chart;
        }
        List<BizCustomerVO> bizCustomers = bizResponse.get();
        // 根据第一次下单时间赋值新老客
        markNewOrOldCustomer(bizCustomers);
        List<String> bizCodes = bizCustomers.stream().map(BizCustomerVO::getCode).filter(Objects::nonNull).collect(Collectors.toList());
        // 查全部
        List<Map> maps = getToBCustomerList(bizCustomers, bizCodes, orgId);
        if (maps.isEmpty()) {
            return chart;
        }

        // 成交量
        Map<Long, BigDecimal> provinceNewNumberOfDealingMap = maps.stream()
                .filter(m -> "新顾客".equals(m.get("newOrOld")))
                .collect(Collectors.groupingBy(
                        m -> (Long) m.get("provinceCode"),
                        Collectors.reducing(
                                BigDecimal.ZERO,
                                m -> (BigDecimal) m.get(IndexConstants.NUMBER_OF_DEALING_FIELD_NAME),
                                BigDecimal::add
                        )
                ));
        Map<Long, BigDecimal> provinceOldNumberOfDealingMap = maps.stream()
                .filter(m -> "老顾客".equals(m.get("newOrOld")))
                .collect(Collectors.groupingBy(
                        m -> (Long) m.get("provinceCode"),
                        Collectors.reducing(
                                BigDecimal.ZERO,
                                m -> (BigDecimal) m.get(IndexConstants.NUMBER_OF_DEALING_FIELD_NAME),
                                BigDecimal::add
                        )
                ));

        List<Map<String, Object>> provinceMaps = maps.stream()
                .collect(Collectors.groupingBy(
                        map -> map.get("provinceCode"),
                        Collectors.groupingBy(
                                map -> map.get("newOrOld"),
                                Collectors.counting()
                        )
                ))
                .entrySet().stream()
                .map(entry -> {
                    Map<String, Object> result = new HashMap<>();
                    result.put("provinceCode", entry.getKey());
                    result.put("newOrOldCount", entry.getValue());
                    return result;
                })
                .sorted(Comparator.comparing(
                        (Map<String, Object> map) -> {
                            Map<Object, Long> newOrOldCount = (Map<Object, Long>) map.get("newOrOldCount");
                            return newOrOldCount.values().stream().mapToLong(Long::longValue).sum();
                        },
                        Comparator.reverseOrder()
                ))
                .collect(Collectors.toList());

        // 获取所有省份
        RegionListQry regionListQry = new RegionListQry();
        regionListQry.setType(2);
        Response<List<RegionVO>> regionResponse = regionRemoteService.selectList(regionListQry);
        if (!regionResponse.isSuccess() || regionResponse.getData().isEmpty()) {
            return chart;
        }
        List<RegionVO> regionList = regionResponse.getData();
        List<Map<String, Object>> topFiveMaps = provinceMaps.stream()
                .limit(10)
                .collect(Collectors.toList());
        for (Map<String, Object> map : topFiveMaps) {
            List<Object> data = new ArrayList<>();
            Long provinceCode = (Long) map.get("provinceCode");
            regionList.stream().filter(regionVO -> regionVO.getId().equals(provinceCode)).findFirst().ifPresent(e -> data.add(e.getName()));
            Map<String, Long> newOrOldCount = (Map<String, Long>) map.computeIfAbsent("newOrOldCount", k -> new HashMap<>());
            data.add(newOrOldCount.get("新顾客") == null ? 0 : newOrOldCount.get("新顾客"));
            data.add(newOrOldCount.get("老顾客") == null ? 0 : newOrOldCount.get("老顾客"));
            data.add(provinceNewNumberOfDealingMap.get(provinceCode) == null ? 0 : provinceNewNumberOfDealingMap.get(provinceCode).intValue());
            data.add(provinceOldNumberOfDealingMap.get(provinceCode) == null ? 0 : provinceOldNumberOfDealingMap.get(provinceCode).intValue());

            datas.add(data);
        }

        List<String> items = chart.getItems();
        items.add("新客数");
        items.add("老客数");
        items.add("新客成交量");
        items.add("老客成交量");
        chart.setDatas(datas).setItems(items);
        return chart;
    }

    public List<Map> getToBCustomerList(List<BizCustomerVO> bizCustomers,List<String> bizCodes, Long orgId) {
        // 查全部
        String year = String.valueOf(LocalDate.now().getYear());
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT * FROM ads_base_biz_customer WHERE  org_id = ")
                .append(orgId)
                .append(" and year = ")
                .append(year);
        if (ObjectUtils.isNotEmpty(bizCodes)){
            sql.append(" and customer_code in (");
            for (String bizCode : bizCodes) {
                sql.append("\"")
                        .append(bizCode)
                        .append("\"")
                        .append(",");
            }
            sql.deleteCharAt(sql.length() - 1);
            sql.append(")");
        }
//        sql.append("group by customer_id ORDER BY number_of_dealing");
        List<Map> maps = jdbcService.selectList(sql.toString(), new Object[]{});

        // 给map赋值省份id、省份名称、客户类型和合作类型、新老客
        if (ObjectUtils.isNotEmpty(bizCustomers)) {
            for (Map map : maps) {
                bizCustomers.stream().filter(e -> e.getCode().equals(map.get("customer_code"))).findFirst().ifPresent(biz -> {
                    map.put("provinceCode", biz.getProvinceId());
                    map.put("provinceName", biz.getProvinceName());
                    map.put("type", biz.getType());
                    map.put("newOrOld", biz.getRemark());
//                map.put("coopType", biz.getCoopType());
                });
            }
        }
        maps = maps.stream().filter(e -> ObjectUtils.isNotEmpty(e.get("provinceCode"))).collect(Collectors.toList());
        return maps;
    }

    public void markNewOrOldCustomer(List<BizCustomerVO> bizCustomers) {
        LocalDateTime now = LocalDateTime.now();

        for (BizCustomerVO customer : bizCustomers) {
            LocalDateTime firstOrderTime = customer.getFirstOrderTime();
            if (firstOrderTime != null) {
                long daysBetween = ChronoUnit.DAYS.between(firstOrderTime, now);
                if (daysBetween <= 365) {
                    customer.setRemark("新顾客");
                } else {
                    customer.setRemark("老顾客");
                }
            } /*else {
                // 处理 firstOrderTime 为 null 的情况
                customer.setRemark("未知");
            }*/
        }
    }

    @Override
    public String getReportName() {
        return "全国成交量Top排名";
    }
}
